package com.sakura.oj.sandbox.template;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import cn.hutool.dfa.WordTree;
import com.sakura.oj.sandbox.CodeSandbox;
import com.sakura.oj.sandbox.model.ExecuteCodeRequest;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 代码沙箱工厂类
 * 负责创建和选择合适的沙箱实现
 */
@Slf4j
@Component
public class CodeSandboxFactory {

    /**
     * 语言类型常量
     */
    public static final String LANGUAGE_JAVA = "java";
    public static final String LANGUAGE_PYTHON = "python";
    public static final String LANGUAGE_CPP = "cpp";
    public static final String LANGUAGE_C = "c";
    
    /**
     * 运行模式常量
     */
    public static final String MODE_DOCKER = "docker";
    public static final String MODE_NATIVE = "native";
    
    /**
     * 默认运行模式
     */
    private static final String DEFAULT_MODE = MODE_DOCKER;
    
    /**
     * 沙箱实例缓存，避免重复创建
     * 格式: language:mode -> 实例
     */
    private final Map<String, CodeSandbox> sandboxCache = new ConcurrentHashMap<>();
    
    /**
     * Spring自动注入所有的沙箱实现
     */
    @Resource
    private Map<String, AbstractCodeSandbox> sandboxMap;
    
    /**
     * 根据语言和模式选择合适的沙箱实现
     *
     * @param language 语言类型
     * @param mode     运行模式 (docker/native)
     * @return 代码沙箱实例
     */
    public CodeSandbox getSandbox(String language, String mode) {
        // 标准化语言类型（统一小写）
        String normalizedLanguage = language.toLowerCase();
        
        // 如果没有指定模式，使用默认模式
        if (mode == null || mode.trim().isEmpty()) {
            mode = DEFAULT_MODE;
        }
        
        // 查找缓存
        String key = normalizedLanguage + ":" + mode;
        if (sandboxCache.containsKey(key)) {
            return sandboxCache.get(key);
        }
        
        // 根据语言和模式查找实现类的Bean名称
        String beanName = normalizedLanguage + mode.substring(0, 1).toUpperCase() + mode.substring(1) + "Sandbox";
        
        // 查找实现类
        if (sandboxMap.containsKey(beanName)) {
            CodeSandbox sandbox = sandboxMap.get(beanName);
            sandboxCache.put(key, sandbox);
            return sandbox;
        }
        
        // 如果没找到实现，抛出异常
        throw new UnsupportedOperationException("不支持的语言或运行模式: " + language + ":" + mode);
    }
    
    /**
     * 根据请求选择合适的沙箱实现
     *
     * @param request 执行代码请求
     * @return 代码沙箱实例
     */
    public CodeSandbox getSandbox(ExecuteCodeRequest request) {
        // 从请求中获取语言类型
        String language = request.getLanguage();
        
        // 目前没有在请求中指定模式，统一使用默认的Docker模式
        return getSandbox(language, DEFAULT_MODE);
    }
} 